package com.gitee.wsl.coroutines.job.listener

import com.gitee.wsl.api.Matcher
import com.gitee.wsl.coroutines.job.JobKey
import com.gitee.wsl.coroutines.job.sheduler.ISchedulerListener
import com.gitee.wsl.coroutines.job.trigger.ITriggerListener
import com.gitee.wsl.coroutines.job.trigger.TriggerKey

interface IListenerManager {
    /**
     * Add the given `[IJobListener]` to the
     * `Scheduler`, and register it to receive events for all Jobs.
     * Because no matchers are provided, the `EverythingMatcher` will
     * be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addJobListener(jobListener: IJobListener)

    /**
     * Add the given `[IJobListener]` to the
     * `Scheduler`, and register it to receive events for Jobs that are
     * matched by the given Matcher. If no matchers are provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addJobListener(jobListener: IJobListener, matcher: Matcher<JobKey>)

    /**
     * Add the given `[IJobListener]` to the
     * `Scheduler`, and register it to receive events for Jobs that are
     * matched by ANY of the given Matchers. If no matchers are provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addJobListener(jobListener: IJobListener, vararg matchers: Matcher<JobKey>)

    /**
     * Add the given `[IJobListener]` to the
     * `Scheduler`, and register it to receive events for Jobs that are
     * matched by ANY of the given Matchers. If no matchers are provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addJobListener(jobListener: IJobListener, matchers: List<Matcher<JobKey>>)

    /**
     * Add the given Matcher to the set of matchers for which the listener will
     * receive events if ANY of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matcher
     * the additional matcher to apply for selecting events
     * @return true if the identified listener was found and updated
     */
    fun addJobListenerMatcher(listenerName: String, matcher: Matcher<JobKey>): Boolean

    /**
     * Remove the given Matcher to the set of matchers for which the listener will
     * receive events if ANY of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matcher
     * the additional matcher to apply for selecting events
     * @return true if the given matcher was found and removed from the listener's
     * list of matchers
     */
    fun removeJobListenerMatcher(listenerName: String, matcher: Matcher<JobKey>): Boolean

    /**
     * Set the set of Matchers for which the listener will receive events if ANY
     * of the matchers match.
     *
     *
     * Removes any existing matchers for the identified listener!
     *
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matchers
     * the matchers to apply for selecting events
     * @return true if the given matcher was found and removed from the listener's
     * list of matchers
     */
    fun setJobListenerMatchers(listenerName: String, matchers: List<Matcher<JobKey>>): Boolean

    /**
     * Get the set of Matchers for which the listener will receive events if ANY
     * of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @return the matchers registered for selecting events for the identified
     * listener
     */
    fun getJobListenerMatchers(listenerName: String): List<Matcher<JobKey>>?

    /**
     * Remove the identified `[IJobListener]` from the
     * `Scheduler`.
     *
     * @return true if the identified listener was found in the list, and removed.
     */
    fun removeJobListener(name: String): Boolean

    /**
     * Get a List containing all of the `[IJobListener]`s in the
     * `Scheduler`, in the order in which they were registered.
     */
    val jobListeners: List<IJobListener>

    /**
     * Get the `[IJobListener]` that has the given name.
     */
    fun getJobListener(name: String): IJobListener?

    /**
     * Add the given `[ITriggerListener]` to the
     * `Scheduler`, and register it to receive events for all Triggers.
     * Because no matcher is provided, the `EverythingMatcher` will be
     * used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addTriggerListener(triggerListener: ITriggerListener)

    /**
     * Add the given `[ITriggerListener]` to the
     * `Scheduler`, and register it to receive events for Triggers that
     * are matched by the given Matcher. If no matcher is provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addTriggerListener(triggerListener: ITriggerListener, matcher: Matcher<TriggerKey>)

    /**
     * Add the given `[ITriggerListener]` to the
     * `Scheduler`, and register it to receive events for Triggers that
     * are matched by ANY of the given Matchers. If no matcher is provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addTriggerListener(
        triggerListener: ITriggerListener,
        vararg matchers: Matcher<TriggerKey>,
    )

    /**
     * Add the given `[ITriggerListener]` to the
     * `Scheduler`, and register it to receive events for Triggers that
     * are matched by ANY of the given Matchers. If no matcher is provided, the
     * `EverythingMatcher` will be used.
     *
     * @see Matcher
     *
     * @see com.helger.quartz.impl.matchers.EverythingMatcher
     */
    fun addTriggerListener(
        triggerListener: ITriggerListener,
        matchers: List<Matcher<TriggerKey>>,
    )

    /**
     * Add the given Matcher to the set of matchers for which the listener will
     * receive events if ANY of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matcher
     * the additional matcher to apply for selecting events
     * @return true if the identified listener was found and updated
     */
    fun addTriggerListenerMatcher(listenerName: String, matcher: Matcher<TriggerKey>): Boolean

    /**
     * Remove the given Matcher to the set of matchers for which the listener will
     * receive events if ANY of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matcher
     * the additional matcher to apply for selecting events
     * @return true if the given matcher was found and removed from the listener's
     * list of matchers
     */
    fun removeTriggerListenerMatcher(
        listenerName: String,
        matcher: Matcher<TriggerKey>,
    ): Boolean

    /**
     * Set the set of Matchers for which the listener will receive events if ANY
     * of the matchers match.
     *
     *
     * Removes any existing matchers for the identified listener!
     *
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @param matchers
     * the matchers to apply for selecting events
     * @return true if the given matcher was found and removed from the listener's
     * list of matchers
     */
    fun setTriggerListenerMatchers(
        listenerName: String,
        matchers: List<Matcher<TriggerKey>>,
    ): Boolean

    /**
     * Get the set of Matchers for which the listener will receive events if ANY
     * of the matchers match.
     *
     * @param listenerName
     * the name of the listener to add the matcher to
     * @return the matchers registered for selecting events for the identified
     * listener
     */
    fun getTriggerListenerMatchers(listenerName: String): List<Matcher<TriggerKey>>

    /**
     * Remove the identified `[ITriggerListener]` from the
     * `Scheduler`.
     *
     * @return true if the identified listener was found in the list, and removed.
     */
    fun removeTriggerListener(name: String): Boolean

    /**
     * Get a List containing all of the `[ITriggerListener]`s in
     * the `Scheduler`, in the order in which they were registered.
     */
    val triggerListeners: List<ITriggerListener>

    /**
     * Get the `[ITriggerListener]` that has the given name.
     */
    fun getTriggerListener(name: String): ITriggerListener?

    /**
     * Register the given `[ISchedulerListener]` with the
     * `Scheduler`.
     */
    fun addSchedulerListener(schedulerListener: ISchedulerListener)

    /**
     * Remove the given `[ISchedulerListener]` from the
     * `Scheduler`.
     *
     * @return true if the identified listener was found in the list, and removed.
     */
    fun removeSchedulerListener(schedulerListener: ISchedulerListener): Boolean

    /**
     * Get a List containing all of the `[ISchedulerListener]`s
     * registered with the `Scheduler`, in the order in which they were
     * registered.
     */
    val schedulerListeners: List<ISchedulerListener>
}
